﻿Shader "Unlit/S_Heatmap"
{
  Properties
  {
    _Alpha("Alpha", Range(0, 1)) = 0.6 // 透明度
    _ColorBase("Base Color", Color) = (0.016, 0.3, 0.13, 1) // 基础颜色
    _Color1("Color 1", Color) = (0, 0.9, 0.2, 1) // 颜色1
    _Color2("Color 2", Color) = (0.9, 1, 0.3, 1) // 颜色2
    _Color3("Color 3", Color) = (0.9, 0.7, 0.1, 1) // 颜色3
    _Color4("Color 4", Color) = (1, 0, 0, 1) // 颜色4

    _Range0("Range 0", Range(0, 1)) = 0.0 // 范围0
    _Range1("Range 1", Range(0, 1)) = 0.25 // 范围1
    _Range2("Range 2", Range(0, 1)) = 0.5 // 范围2
    _Range3("Range 3", Range(0, 1)) = 0.75 // 范围3
    _Range4("Range 4", Range(0, 1)) = 1.0 // 范围4

    _Diameter("Diameter", Range(0, 1)) = 1.0 // 直径
    _Strength("Strength", Range(0.01, 4)) = 1.0 // 强度
    _PulseSpeed("Pulse Speed", Range(0, 5)) = 0 // 脉冲速度
  }
  SubShader
  {
    Tags { 
      "RenderType" = "Transparent" 
      "Queue" = "Transparent"
    }
    ZTest Less
    Blend SrcAlpha OneMinusSrcAlpha
    LOD 100

    Pass
    {
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag

      #include "UnityCG.cginc"

      struct appdata
      {
        float4 vertex : POSITION; // 顶点位置
        float2 uv : TEXCOORD0; // UV坐标
      };

      struct v2f
      {
        float2 uv : TEXCOORD0; // UV坐标
        float4 vertex : SV_POSITION; // 裁剪空间位置
      };

      float4 _ColorBase;
      float4 _Color1;
      float4 _Color2;
      float4 _Color3;
      float4 _Color4;

      float _Alpha;
      float _Range0;
      float _Range1;
      float _Range2;
      float _Range3;
      float _Range4;
      float _Diameter;
      float _Strength;

      float _PulseSpeed;

      // 顶点着色器函数
      v2f vert(appdata v)
      {
        v2f o;
        o.vertex = UnityObjectToClipPos(v.vertex); // 将顶点位置转换到裁剪空间
        o.uv = v.uv; // 传递UV坐标
        return o;
      }

      float3 colors[5]; // 用于点范围的颜色数组
      float pointRanges[5]; // 用于颜色渐变的范围数组
      float _Hits[3 * 32]; // 存储点的位置和强度的数组
      int _HitCount = 0; // 点的数量

      // 初始化颜色和范围数组
      void initialize()
      {
        colors[0] = _ColorBase.rgb; // 初始化颜色数组
        colors[1] = _Color1.rgb;
        colors[2] = _Color2.rgb;
        colors[3] = _Color3.rgb;
        colors[4] = _Color4.rgb;
        pointRanges[0] = _Range0; // 初始化范围数组
        pointRanges[1] = _Range1;
        pointRanges[2] = _Range2;
        pointRanges[3] = _Range3;
        pointRanges[4] = _Range4;
      }

      // 根据权重获取对应的热力图颜色
      float3 getHeatForPixel(float weight)
      {
        if (weight <= pointRanges[0]) return colors[0]; // 如果权重小于等于最小范围，返回最小颜色
        if (weight >= pointRanges[4]) return colors[4]; // 如果权重大于等于最大范围，返回最大颜色

        for (int i = 1; i < 5; i++)
        {
          if (weight < pointRanges[i])
          {
            float ratio = (weight - pointRanges[i - 1]) / (pointRanges[i] - pointRanges[i - 1]); // 计算权重在两个范围之间的比例
            return lerp(colors[i - 1], colors[i], ratio); // 根据比例进行颜色插值
          }
        }
        return colors[0]; // 默认返回最小颜色
      }

      // 计算两点之间的距离平方
      float calculateDistanceSquared(float2 a, float2 b)
      {
        float areaOfEffectSize = _Diameter; // 影响范围的直径
        return pow(max(0.0, 1.0 - distance(a, b) / areaOfEffectSize), 2.0); // 计算距离的平方
      }

      // 片段着色器函数
      float4 frag(v2f i) : SV_Target
      {
        initialize(); // 初始化颜色和范围数组
        float2 uv = i.uv * 4.0 - float2(2.0, 2.0); // 将UV坐标转换到-2到2的范围

        float totalWeight = 0.0; // 总权重
        for (int j = 0; j < _HitCount; j++)
        {
          float2 pointPosition = float2(_Hits[j * 3], _Hits[j * 3 + 1]); // 获取点的位置
          float pointIntensity = _Hits[j * 3 + 2]; // 获取点的强度
          totalWeight += 0.5 * calculateDistanceSquared(uv, pointPosition) * pointIntensity * _Strength * (1 + sin(_Time.y * _PulseSpeed)); // 计算总权重
        }
        return float4(getHeatForPixel(totalWeight), _Alpha); // 返回最终的颜色和透明度
      }
      ENDCG
    }
  }
}
